#include "herm/base/utils/misc.h"
#include "sock_buffer.h"
#include "nbc_tcp_session.h"

void NonblockConnectTCPSession::Reset(herm::Handle handle, herm::INBCNotifier* notifier)
{
	m_isConnected = false;
	TCPSession::Reset(handle, false);
	m_notifier = notifier;
}

int NonblockConnectTCPSession::Read(char* buf, int& len)
{
	int ret = TCPSession::Fetch(buf, len);
	if (ret == herm::ST_EXCEPT_FAILED)
	{
		if (!m_isConnected)
			m_notifier->Connect(false);
	}

	return ret;
}

int NonblockConnectTCPSession::Send(int)
{
	if (!m_isConnected)
	{
		m_isConnected = true;
		m_notifier->Connect(true);
	}

	return TCPSession::OnSend(0);
}

int NonblockConnectTCPSession::Push(const char* buf, int len)
{
    if (len < 0 || len > m_peerParam->sendTCPBufSize)
        return herm::ST_INVALID_MSG;

	if (!m_isConnected) // Connecting, only write queue, don't send
	{
		// PreSend, encryption
		if (m_msgHandler->IsPreSend())
		{
			int outLen = m_peerParam->recvTCPBufSize;
			int ret = m_msgHandler->PreSend(buf, len, m_tmpBuf, outLen);
			if (ret != herm::ST_SUCCESS)
				return ret;

			if (!m_sendBuffer->Push(m_tmpBuf, outLen))
				return herm::ST_BUFF_FULL;
		}
		else
		{
			// Note, SendQueue->Push will write all data or nothing
			if (!m_sendBuffer->Push(buf, len))
				return herm::ST_BUFF_FULL;
		}
	}
	else
		return TCPSession::Push(buf, len);

	return herm::ST_SUCCESS;
}
